package org.mullin.stratego.shared;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Random;
import java.util.RandomAccess;

public class RandomState {
	
	Map<Rank, Integer> rankCounts;
	
	public RandomState() {
		rankCounts = new HashMap<Rank, Integer>();
		rankCounts.put(Rank.MARSHAL, 1);
		rankCounts.put(Rank.GENERAL, 1);
		rankCounts.put(Rank.COLONEL, 2);
		rankCounts.put(Rank.MAJOR, 3);
		rankCounts.put(Rank.CAPTAIN, 4);
		rankCounts.put(Rank.LIEUTENANT, 4);
		rankCounts.put(Rank.SERGEANT, 4);
		rankCounts.put(Rank.SAPPER, 5);
		rankCounts.put(Rank.SCOUT, 8);
		rankCounts.put(Rank.SPY, 1);
		rankCounts.put(Rank.BOMB, 6);
		rankCounts.put(Rank.FLAG, 1);
	}
	
	private static final int SHUFFLE_THRESHOLD        =    5;
	
	public static void swap(List<?> list, int i, int j) {
		final List l = list;
		l.set(i, l.set(j, l.get(i)));
	}
	
	private static void swap(Object[] arr, int i, int j) {
		Object tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}
	
	public static void shuffle(List<?> list, Random rnd) {
	    int size = list.size();
	    if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
	        for (int i=size; i>1; i--)
	            swap(list, i-1, rnd.nextInt(i));
	    } else {
	        Object arr[] = list.toArray();

	        // Shuffle array
	        for (int i=size; i>1; i--)
	            swap(arr, i-1, rnd.nextInt(i));

	        // Dump array back into list
	        ListIterator it = list.listIterator();
	        for (int i=0; i<arr.length; i++) {
	            it.next();
	            it.set(arr[i]);
	        }
	    }
	}
	
	public State generateRandomStartingState() {
		Random rand = new Random();
		State ret = new State();
		
		//for (int color = Color.RED; color < Color.BLUE; color++) {
		List<Piece> redPieces = new ArrayList<Piece>();
		List<Piece> bluePieces = new ArrayList<Piece>();
		for (Rank r : rankCounts.keySet()) {
			for (int i = 0; i < rankCounts.get(r); i++) {
				Piece redPiece = new Piece(Color.RED, r);
				Piece bluePiece = new Piece(Color.BLUE, r);
				redPieces.add(redPiece);
				bluePieces.add(bluePiece);
			}
		}
		shuffle(redPieces, rand);
		shuffle(bluePieces, rand);

		Iterator<Piece> it = redPieces.iterator();
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 10; j++) {
				Coord c = new Coord(i, j);
				Piece p = it.next();
				ret.setPiece(p, c);
			}
		}
		
		it = bluePieces.iterator();
		for (int i = 6; i < 10; i++) {
			for (int j = 0; j < 10; j++) {
				Coord c = new Coord(i, j);
				Piece p = it.next();				
				ret.setPiece(p, c);
			}
		}
		//}			
		
		return ret;
	}
}
